import {Headers, Http, RequestOptions, Response} from "@angular/http";
import {LogUtil} from "../../util/log-util";
import {TokenUtil} from "../../util/token-util";
import {Observable} from "rxjs/Observable";
import {MsgResult} from "../../models/msg-result";
import {Injectable} from "@angular/core";
import {HttpClientInterface} from "./http-client-interface";
/**
 * Created by duqunxing on 2017/8/31.
 */

@Injectable()
export class CustomHttp implements HttpClientInterface{
  constructor(
    private http:Http,
    private logUtil : LogUtil,
    private tokenUtil : TokenUtil
  ){
  }

  get(api:string,params?:string): Observable<MsgResult> | any{
    return  this.http.get(this.wrapToUrl(api,params),this.getNoCahcheRequestOptions())
      .map(res =>this.success(res))
      .catch(error => this.error(error));
  }

  post(api:string,params?:string): Observable<MsgResult> | any{
    return this.http.post(api,params,this.getRequestOptions())
      .map(res =>this.success(res))
      .catch(error => this.error(error));
  }

  put(api:string,params?:string): Observable<MsgResult> | any{
    return this.http.put(api,params,this.getRequestOptions())
      .map(res => this.success(res))
      .catch(error => this.error(error));
  }

  delete(api:string,params?:string): Observable<MsgResult> | any{
    return this.http.delete(this.wrapToUrl(api,params),this.getRequestOptions())
      .map(res => this.success(res))
      .catch(error => this.error(error));
  }

  patch(api:string,params?:string): Observable<MsgResult> | any{
    return this.http.patch(api,params,this.getRequestOptions())
      .map(res => this.success(res))
      .catch(error => this.error(error));
  }

  head(api:string,params?:string): Observable<MsgResult> | any{
    return this.http.head(this.wrapToUrl(api,params),this.getRequestOptions())
      .map(res => this.success(res))
      .catch(error => this.error(error));
  }

  options(api:string,params?:string): Observable<MsgResult> | any{
    return this.http.options(this.wrapToUrl(api,params),this.getRequestOptions())
      .map(res => this.success(res))
      .catch(error => this.error(error));
  }
  postWithData(api:string,params?:string): Observable<any> | any{
    return this.http.post(api,params,this.getRequestOptions());
  }
  getFile(api:string,params?:string): Observable<ArrayBuffer> | any{
    return  this.http.get(this.wrapToUrl(api,params),this.getFileRequestOptions())
      .map(res => { return res.arrayBuffer()})
      .catch(error => this.error(error));
  }
  /**
   * 封装api和param成url
   * @param api
   * @param params
   * @returns {any}
   */
  private wrapToUrl(api:string,params?:string):string{
    if(!!!params){
      return api;
    }
    let url;
    if(api.indexOf("?") != -1){
      let orginParmas =  api.substr(api.indexOf("?") + 1);
      let uri = api.substring(0,api.indexOf("?"));
      url = uri + "?" + (orginParmas.length > 0 ? orginParmas + "&" : "")+ params;
    }else{
      url = api + "?" + params;
    }
    return url;
  }

  /**
   * 处理请求头
   * @returns {RequestOptions}
   */
  private getRequestOptions(){
    let headers = new Headers({'Content-Type': 'application/x-www-form-urlencoded'});
    headers.append('X-Requested-With', 'XMLHttpRequest' );
    headers.append("Authorization","Bearer " + this.tokenUtil.getToken());
    let _defaultOptions = new RequestOptions({headers: headers});
    return _defaultOptions;
  }

  /**
   * 构建不缓存数据的请求
   * 修复在IE11下get请求被缓存，导致数据无刷新bug
   * @returns {RequestOptions}
   */
  private getNoCahcheRequestOptions(){
    let headers = new Headers({'Content-Type': 'application/x-www-form-urlencoded'});
    headers.append('X-Requested-With', 'XMLHttpRequest' );
    headers.append("Cache-Control","no-cache");
    headers.append("Pragma","no-cache");
    headers.append("Expires","Sat, 01 Jan 2000 00:00:00 GMT");
    headers.append("Authorization","Bearer " + this.tokenUtil.getToken());
    let _defaultOptions = new RequestOptions({headers: headers});
    return _defaultOptions;
  }

  /**
   * 流下载请求项
   * @returns {RequestOptions}
   */
  private getFileRequestOptions(){
    let headers = new Headers({'Content-Type': 'application/x-www-form-urlencoded'});
    headers.append('X-Requested-With', 'XMLHttpRequest' );
    headers.append("Cache-Control","no-cache");
    headers.append("Pragma","no-cache");
    headers.append("Expires","Sat, 01 Jan 2000 00:00:00 GMT");
    headers.append("Authorization","Bearer " + this.tokenUtil.getToken());
    let _defaultOptions = new RequestOptions({headers: headers,responseType: 2});
    return _defaultOptions;
  }



  /**
   * 成功处理
   * @param res
   * @returns {any}
   */
  private success(res :Response){
    let json = res.json();
    return json;
  }

  /**
   * 失败处理
   * @param error
   * @returns {string}
   */
  private error(error: Response | any){
    let errMsg: string;
    if (error instanceof Response) {
      const body = error.json() || '';
      const err = body.error || JSON.stringify(body);
      errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
    } else {
      errMsg = error.message ? error.message : error.toString();
    }
    this.logUtil.error(errMsg);
    return errMsg;
  }
}
